import sys, os
from Output import output
import glob, time, random

class handler:
    MSG501 = "Status: 501 Not Implemented\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n"
    MSG404 = "Status: 404 Not Found\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n"
    MSG0LEN = "Content-Length: 0\r\nContent-Type: text/plain\r\n\r\n"
    defaultuser = "shafiq"
    PUT_REMOVE_TIMEOUT = 30        # start removing older m3u8 after 120 seconds
    
    def __init__(self, user="shafiq", mode=output.STDMODE, mask = output.GET_PUT_Request):
        self.output = output(user, mode, mask)
        
    def handle(self, method, name, contentType):
        self.output.clear()
        self.output.logthis("Handler:: handle :: Begin")
        self.output.logthis("Handler:: handle :: Method: " + method + " \r + Name: " + name + " \r + Content: " + contentType)
        
        if name.endswith(".m3u8") or name.endswith("thumb.jpg"):
            if method == "PUT":
                self.HandleM3u8_PUT(name, contentType)
            elif method == "GET":
                self.output.logthis("ReqHandler::handle() :: GET -> Control should never reach here: " + name + " Method " + method, output.GET_Request)
                #self.HandleM3u8_GET(name, contentType)
            else:
                self.output.logthis("handle:: " + method + " not implemented for " + name)
                self.output.logthis("returning 501 for " + method + " and " + name)
                sys.stdout.write(self.MSG501)
        self.output.logthis("Handler:: handle :: End")
        
    def HandleM3u8_PUT(self, name, contentType):
        self.output.logthis("\r HandleM3u8_PUT() Begin for " + name, output.PUT_Request)
        names = glob.glob("%s-*" % name)
        name = "%s-%d-%d" % (name, time.time(), random.randint(100000,999999))
        self.WriteStdinToFile(name)
        
        #remove older name-m3u8.* if they are older than TIMEOUT
        minThreshold = os.path.getmtime(name) - self.PUT_REMOVE_TIMEOUT    #min threshold
        while len(names) > 2:       # more than one timestamps for name.m3u8 exists
            (accessTime, filename) = min((self.GetModifiedTime(filename), filename) for filename in names)
            if accessTime > minThreshold:
                break       # ignore m3u8 generated within the last PUT_REMOVE_TIMEOUT
                            # do not consider other files, since the minimum is selected and if that is within the threshold, all the others will already be within the threshold
            #otherwise try to remove it if it has not been removed already
            try:
                self.output.logthis("trying to remove " + filename, output.PUT_Request)
                os.remove(filename)
            except:
                self.output.logthis("failed to remove " + filename, output.PUT_Request)
            names.remove(filename)
            
        sys.stdout.write("Content-Length: 0\r\n\r\n")
        self.output.logthis("\r HandleM3u8_PUT() End for " + name, output.PUT_Request)
        
    def HandleM3u8_GET(self, name, contentType):
        self.output.logthis("\r HandleM3u8_GET() Begin for " + name, output.GET_Request)
                   
        self.output.logthis("\r HandleM3u8_GET() End for " + name, output.GET_Request)
    
    def WriteStdinToFile(self, name):
        self.output.logthis("\r\r>>>>>>>>>>>>>>>WriteStdinToFile:: " + name)
        fileHandle = open(name, "wb")      
        while True:
            next = sys.stdin.read(4096)
            if not next:
                break
            fileHandle.write(next)
        fileHandle.close()
        
    def GetModifiedTime(self, name):
        try:
            return os.path.getmtime(name)
        except:
            self.output.logthis("GetModifiedTime failed to retreive time for " + name, output.GET_PUT_Request)
            return 0    #in case the file-name does not exist when the modified time is queried